package com.rollCall.service.app.impl;

import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.rollCall.common.constant.MessageConstant;
import com.rollCall.common.util.UserHolder;
import com.rollCall.entity.*;
import com.rollCall.entity.vo.AppCheckInVo;
import com.rollCall.entity.vo.LoginVo;
import com.rollCall.entity.vo.StudentLoginVo;
import com.rollCall.entity.vo.StudentVo;
import com.rollCall.mapper.*;
import com.rollCall.service.StudentService;
import com.rollCall.service.app.AppStudentService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.List;
import java.util.Objects;
import java.util.UUID;
import java.util.function.Function;
import java.util.stream.Collectors;

import static com.rollCall.common.constant.MessageConstant.ACCOUNT_NOT_FOUND;

/**
 * @author LiZhiHan
 * @date 2025/2/28
 */
@Service
@RequiredArgsConstructor
@Slf4j
public class AppStudentServiceImpl implements AppStudentService {

	private final StudentMapper studentMapper;

	private final JwtMapper jwtMapper;

	private final ClassMapper classMapper;

	private final CheckInRecordMapper checkInRecordMapper;

	private final CheckInMapper checkInMapper;

	private final AdminMapper adminMapper;

	/**
	 * 学生登录
	 */
	@Override
	public String login(StudentLoginVo studentLoginVo) {
		// 获取学生信息
		Student student = studentMapper.selectOne(new QueryWrapper<Student>().eq("uid", studentLoginVo.getUid()));
		if (ObjectUtil.isNull(student)) {
			throw new RuntimeException(ACCOUNT_NOT_FOUND);
		}
		if (!student.getPassword().equals(studentLoginVo.getPassword())) {
			throw new RuntimeException(MessageConstant.PASSWORD_ERROR);
		}
		log.info("登录成功");
		Jwt jwt = jwtMapper.selectOne(new QueryWrapper<Jwt>().eq("student_id", student.getId()));
		String uuid = null;
		if (ObjectUtil.isNull(jwt)) {
			jwt = new Jwt();
			jwt.setStudentId(student.getId());
			uuid = UUID.randomUUID().toString();
			jwt.setJwt(uuid);
			jwtMapper.insert(jwt);
		} else {
			uuid = jwt.getJwt();
		}
		return uuid;
	}

	@Override
	public StudentVo myInfo() {
		Long studentId = UserHolder.get();
		Student student = studentMapper.selectById(studentId);
		StudentVo studentVo = new StudentVo();
		studentVo.setId(student.getId());
		studentVo.setName(student.getName());
		studentVo.setClassName(classMapper.selectById(student.getClassId()).getName());
		studentVo.setUid(student.getUid());
		return studentVo;
	}

	public List<AppCheckInVo> list(Integer status) {
		Long userId = UserHolder.get();
		List<CheckInRecord> checkInRecordList = checkInRecordMapper.selectList(new QueryWrapper<CheckInRecord>().eq("student_id", userId));
		if (status == -1) {
			// 获取全部
			return checkInRecordList.stream().map(getCheck()).collect(Collectors.toList());
		}

		return checkInRecordList.stream().filter(f -> Objects.equals(f.getStatus(), status)).map(getCheck()).collect(Collectors.toList());
	}

	@Override
	public void checkIn(Long checkInId) {
		LocalDateTime now = LocalDateTime.now();
		QueryWrapper<CheckInRecord> eq = new QueryWrapper<CheckInRecord>().eq("student_id", UserHolder.get())
												 .eq("check_in_id", checkInId);
		if (checkInRecordMapper.selectCount(eq) != 0) {
			CheckInRecord checkInRecord = checkInRecordMapper.selectOne(eq);
			CheckIn checkIn = checkInMapper.selectById(checkInId);
			if (now.isBefore(checkIn.getExpireTime())) {
				checkInRecord.setStatus(1);
				checkInRecord.setCheckInTime(now);
				checkInRecordMapper.updateById(checkInRecord);
			} else {
				checkInRecord.setStatus(2);
				checkInRecordMapper.updateById(checkInRecord);
				throw new RuntimeException("签到时间已过");
			}
		} else {
			throw new RuntimeException("签到信息不存在");
		}

	}

	private Function<CheckInRecord, AppCheckInVo> getCheck() {
		return checkInRecord -> {
			Long checkInId = checkInRecord.getCheckInId();
			CheckIn checkIn = checkInMapper.selectById(checkInId);
			AppCheckInVo appCheckInVo = new AppCheckInVo();
			appCheckInVo.setStatus(checkInRecord.getStatus());
			appCheckInVo.setId(checkIn.getCheckInId());
			appCheckInVo.setDescription(checkIn.getDescription());
			appCheckInVo.setCreateTime(checkIn.getCreateTime());
			appCheckInVo.setExpireTime(checkIn.getExpireTime());
			appCheckInVo.setClassName(classMapper.selectById(checkIn.getClassId()).getName());
			appCheckInVo.setCheckInTime(checkInRecord.getCheckInTime());
			Admin admin = adminMapper.selectById(checkIn.getAdminId());
			appCheckInVo.setCreatBy(admin.getRealName() == null ? admin.getUsername() : admin.getRealName());
			return appCheckInVo;
		};
	}
}
